﻿using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;

namespace NetScript
{
     class CSharp
     //Creator - HF Tweety
     //Profile - http://www.hackforums.net/member.php?action=profile&uid=1234585
     //Website - www.codeineject.co.uk
     //Twitter - @Codeinject
     /// <summary>
     /// Net Script is a light weight application to run text files as .NET application or scripts
     /// It transforms the language into a scripting language, making it as powerful and easy to use as Batch files or VB 
     /// </summary>
     /// <remarks>
     /// </remarks>
    {
        public static void Main()
        {
            if (Environment.GetCommandLineArgs().Length == 0) { Environment.Exit(0); }

            foreach (string cmdargs in Environment.GetCommandLineArgs())
            {
                if (cmdargs == Application.ExecutablePath) { continue; }
                if (!File.Exists(cmdargs)) { continue; }
                string Source = File.ReadAllText(cmdargs);
                using (Microsoft.CSharp.CSharpCodeProvider CodeProvider = new Microsoft.CSharp.CSharpCodeProvider())
                {

                    CompilerParameters Parameters = new CompilerParameters();
                    try
                    {
                        Parameters.GenerateExecutable = false;
                        Parameters.GenerateInMemory = true;
                        Parameters.ReferencedAssemblies.AddRange(RetrieveReference(Source));
                        CompilerResults Result = CodeProvider.CompileAssemblyFromSource(Parameters, Source);
                        if (Result.Errors.Count != 0)
                        {
                            foreach (CompilerError r in Result.Errors)
                            {
                                Debug.WriteLine("At line " + Convert.ToString(r.Line) + Environment.NewLine + Environment.NewLine + r.ErrorText);
                                MessageBox.Show("At line " + Convert.ToString(r.Line) + Environment.NewLine + Environment.NewLine + r.ErrorText,
                                                "Error", MessageBoxButtons.OK,
                                                    MessageBoxIcon.Error);
                            }
                            return;
                        }
                        object ASM = Result.CompiledAssembly.CreateInstance(RetrieveNamespace(Source) + "." + RetrieveClass(Source));
                        ASM.GetType().GetMethod("Main").Invoke(ASM, null);
                    }
                    catch (Exception ex)
                    {
                        EraseModule(ref Parameters);
                        Console.WriteLine(ex.Message);
                        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        Environment.Exit(0);
                    }
                }
            }
        }

        [STAThread()]
         static void EraseModule(ref CompilerParameters Obj)
        {
            try
            {
                Obj.TempFiles.Delete();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }



        private static String[] RetrieveReference(String Source)
        {
                List<string> RefList = new List<string>();
                foreach (String Import in Source.ToLower().Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
                    {
                        if (Import.ToLower().Contains("using "))
                        {
                            string library = Import.Split(Convert.ToChar(" "))[1].Remove(Import.Split(Convert.ToChar(" "))[1].Length - 1);
                            RefList.Add(library + ".dll");
                        }
                    }
                    return RefList.ToArray();
        }

        private static string RetrieveNamespace(String source)
        {
            string[] realLines = source.Split(Environment.NewLine.ToCharArray());
            for (int i = 0; i < realLines.Length;i++)
            {
                string line = realLines[i].TrimStart(); // this will remove the starting spaces..
                if (line.ToLower().Contains("namespace "))
                {

                    string[] splittedValues = line.Split(' ');

                    return splittedValues[splittedValues.Length - 1];
                }
            }
            return null;
        }

        private static string RetrieveClass(String source)
        {
            string[] realLines = source.Split(Environment.NewLine.ToCharArray());
            for (int i = 0; i < realLines.Length; i++)
            {
                string line = realLines[i].TrimStart(); // this will remove the starting spaces..
                if (line.ToLower().Contains("class "))
                {
                    string[] splittedValues = line.Split(' ');
                    return splittedValues[splittedValues.Length - 1];
                }
            }
            return null;
        }
    }
}